﻿#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>


//struct stu
//{
//	char name[30];
//	char sex[10];
//	int age;
//	float score;
//}s2;
//
//
//int main()
//{
//	struct stu s = { "douxinyi","女",17,555.5f };//按结构体成员顺序初始化
//	struct stu s1 = { "wangkun","男",19,545.5f };
//	//按指定的顺序初始化
//	struct stu s2 = { .name = "zhangsan",.age = 18, .sex = "男",.score = 97.5f };
//	printf("%s %s %d %f\n", s.name, s.sex, s.age, s.score);
//	printf("%s %s %d %f\n", s1.name, s1.sex, s1.age, s1.score);
//	printf("%s %s %d %f\n", s2.name, s2.sex, s2.age, s2.score);
//	return 0;
//}




//结构体可以匿名使用
//只能使用一次
//#define _CRT_SECURE_NO_WARNINGS 1
//#include <stdio.h>
//
//struct
//{
//	int age;
//	char name[20];
//}s1;
//
//int main()
//{
//	s1.age = 10;
//	printf("%d", s1.age);
//	return 0;
//}
//




//结构体的子引用
//struct Node
//{
//	int data;
//	struct Node next;//这样是错的 不能直接自引用，会导致不断的循环
// //正确的方法是存入下一个节点的地址
// struct Node *next;
//};


//
//typedef struct
//{
//	int data;
//	Node* next;   //匿名结构体不能重命名 因为他是被定义为Node才存在的
//      //但是这个匿名结构体还没被命名就是用了就是错误的
//}Node;





//结构体内存对齐

//内存对齐的规则
//1. 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
//2. 其他成员变量要对⻬到某个数字（对⻬数）的整数倍的地址处。
//对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。
//-VS 中默认的值为 8
//- Linux中 gcc 没有默认对⻬数，对⻬数就是成员⾃⾝的⼤⼩
//3. 结构体总⼤⼩为最⼤对⻬数（结构体中每个成员变量都有⼀个对⻬数，所有对⻬数中最⼤的）的整数倍。
//4. 如果嵌套了结构体的情况，嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处，结构
//体的整体⼤⼩就是所有最⼤对⻬数（含嵌套结构体中成员的对⻬数）的整数倍。


//1.
//struct S1
//{
//	char c1;
//	int i;
//	char c2;
//};
////结构体的内存分析
////首先结构体的内存储存有一个偏移量0 1 2 3 4...每一个都对应一个字节 结构体的第一个成员就在偏移量为0的位置
////第二个成员就要对齐到对齐数的正数倍
////(其中对齐数 = 编译器默认的对齐数大小(VS环境的对齐数等于8)和该成员变量大小的较小值)
////(linux和gcc是没有默认的对齐数,对齐数就是成员本身的大小)
////先通过这两个原则来计算结构体的内存
////首先是char c1 它一个字节且是在偏移量为0的位置上 然后是int i
////它是4个字节 它和系统之间的最小值就是4 对齐数为4 要找到4的整数倍就是偏移量为4的位置
////偏移量为4和7都是int i的内存存储 最后在储存char c2 它是一个字节的大小 对齐数为1
////此时整个结构体偏移量为8
////这时候就要看第三个原则
////结构体总大小要是整个结构体成员最大的对齐数 那么最大的对齐数就是4
////4的倍数是12那么这下结构体总大小就是12
//
//int main()
//{
//	printf("%d\n", sizeof(struct S1));//12
//	return 0;
//}


//2.
//struct S2
//{
//	char c1;//第一个成员在偏移量为0的位置 char c1 为1个字节
//	char c2;//对齐数为1 char c2的对齐数的整数倍可以是任何数 那么此时char c2就在偏移量为1的位置
//	int i;//对齐数是4 int i的对齐数的整数倍是 4那么到偏移量7就是int i的位置
//	//结构体总大小就是最大对齐数4的倍数  此时结构体大小为8就是4的倍数
//};
//
//int main()
//{
//	printf("%d\n", sizeof(struct S2));//8
//	return 0;
//}





//3.
//struct S3
//{
//	double d;//对齐数为8 在偏移量为0~7的空间中储存
//	char c;//对齐数为1 在偏移量8的位置
//	int i;//对齐数为4 偏移量9不是4的倍数 则从偏移量12开始存储int i 存储到偏移量为15的位置
//	//此时结构体的总大小为16为最大对齐数8的倍数
//};
//
//int main()
//{
//	printf("%d\n", sizeof(struct S3));//16
//	return 0;
//}




//4.
//struct S3
//{
//	double d;
//	char c;
//	int i;
//};
//
//struct S4
//{
//	char c1;//对齐数为1 偏移量为0的位置
//	struct S3 s3;//这是嵌套的结构体 这里的对齐数是根据嵌套的结构体自己成员中的最大对齐数
//	//对齐数是8  那么从偏移量为8的位置开始存储
//	//8~23的位置都是结构体s3
//	double d;//此时偏移量为24是对齐数为8的倍数，存储8空间
//	//此时结构体的总大小为32 是16的倍数
//};
//
//
//int main()
//{
//	printf("%d\n", sizeof(struct S4));//32
//	return 0;
//}



